package com.campus.secondhand.controller;

import java.math.BigDecimal;
import java.security.Principal;
import java.util.List;
import java.util.ArrayList;

import com.campus.secondhand.mapper.ProductImageMapper;
import com.campus.secondhand.mapper.ProductMapper;
import com.campus.secondhand.service.impl.ProductImageServiceImpl;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.MediaType;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.campus.secondhand.common.Result;
import com.campus.secondhand.entity.User;
import com.campus.secondhand.model.dto.ProductCreateDTO;
import com.campus.secondhand.model.dto.ProductUpdateDTO;
import com.campus.secondhand.model.vo.CategoryTreeVO;
import com.campus.secondhand.model.vo.CategoryVO;
import com.campus.secondhand.model.vo.ProductDetailVO;
import com.campus.secondhand.model.vo.ProductListVO;
import com.campus.secondhand.model.vo.ProductImageVO;
import com.campus.secondhand.service.CategoryService;
import com.campus.secondhand.service.ProductService;
import com.campus.secondhand.service.UserService;
import com.campus.secondhand.service.FavoriteService;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 商品控制器
 */
@RestController
@RequestMapping("/products")
@RequiredArgsConstructor
@Slf4j
public class ProductController {

    private final ProductService productService;
    private final UserService userService;
    private final CategoryService categoryService;
    private final FavoriteService favoriteService;
    private final ProductMapper productMapper;
    private final ProductImageMapper productImageMapper;
    private final ProductImageServiceImpl productImageService;

    /**
     * 获取商品列表
     * 
     * @param category      分类ID
     * @param school        学校ID
     * @param keyword       搜索关键词
     * @param minPrice      最低价格
     * @param maxPrice      最高价格
     * @param sort          排序字段：price, createdAt, views
     * @param order         排序方式：asc, desc
     * @param longitude     经度
     * @param latitude      纬度
     * @param page          页码
     * @param limit         每页数量
     * @param requestUserId 请求用户ID
     * @param principal     当前登录用户
     * @return 商品列表分页结果
     */
    @GetMapping
    public Result<Page<ProductListVO>> getProductList(
            @RequestParam(required = false) Long category,
            @RequestParam(required = false) Long school,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) Double minPrice,
            @RequestParam(required = false) Double maxPrice,
            @RequestParam(required = false, defaultValue = "createdAt") String sort,
            @RequestParam(required = false, defaultValue = "desc") String order,
            @RequestParam(required = false) Double longitude,
            @RequestParam(required = false) Double latitude,
            @RequestParam(required = false, defaultValue = "0") int page,
            @RequestParam(required = false, defaultValue = "10") int limit,
            @RequestParam(required = false) Long requestUserId,
            Principal principal) {

        Long currentUserId = null;
        if (requestUserId != null) {
            currentUserId = requestUserId;
        } else if (principal != null) {
            Result<User> userResult = userService.getByUsername(principal.getName());
            if (userResult.getCode() == 200 && userResult.getData() != null) {
                currentUserId = userResult.getData().getId();
            }
        }

        Pageable pageable = PageRequest.of(page, limit);
        return productService.getProductList(category, school, keyword, minPrice, maxPrice, sort, order, longitude,
                latitude, pageable, currentUserId);
    }

    /**
     * 获取商品详情
     * 
     * @param id        商品ID
     * @param principal 当前登录用户
     * @return 商品详情
     */
    @GetMapping("/{id}")
    public Result<ProductDetailVO> getProductDetail(
            @PathVariable Long id,
            Principal principal) {
        Long userId = null;
        if (principal != null) {
            Result<User> userResult = userService.getByUsername(principal.getName());
            if (userResult.getCode() == 200) {
                userId = userResult.getData().getId();
            }
        }
        return productService.getProductDetail(id, userId);
    }

    /**
     * 发布商品
     * 
     * @param principal           当前登录用户
     * @param name                商品名称
     * @param categoryId          商品分类ID
     * @param price               商品价格
     * @param description         商品描述
     * @param condition           商品成色
     * @param longitude           经度
     * @param latitude            纬度
     * @param locationDescription 位置描述
     * @param files               图片文件列表
     * @return 创建结果
     */
    @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @PreAuthorize("isAuthenticated()")
    public Result<Long> createProduct(
            Principal principal,
            @RequestParam("name") String name,
            @RequestParam("categoryId") Long categoryId,
            @RequestParam("price") Double price,
            @RequestParam("description") String description,
            @RequestParam("condition") String condition,
            @RequestParam("longitude") Double longitude,
            @RequestParam("latitude") Double latitude,
            @RequestParam("locationDescription") String locationDescription,
            @RequestParam("files") List<MultipartFile> files) {

        Result<User> userResult = userService.getByUsername(principal.getName());
        if (userResult.getCode() != 200) {
            return Result.error(userResult.getCode(), userResult.getMessage());
        }

        Long userId = userResult.getData().getId();

        // 1. 上传图片
        List<String> imageUrls = new ArrayList<>();

        for (MultipartFile file : files) {
            if (!file.isEmpty()) {
                Result<String> uploadResult = productService.uploadProductImage(userId, file);
                if (uploadResult.getCode() == 200 && uploadResult.getData() != null) {
                    imageUrls.add(uploadResult.getData());
                } else {
                    return Result.error(500, "图片上传失败");
                }
            }
        }

        if (imageUrls.isEmpty()) {
            return Result.error(400, "请至少上传一张商品图片");
        }

        // 2. 创建商品DTO
        ProductCreateDTO createDTO = new ProductCreateDTO();
        createDTO.setName(name);
        createDTO.setCategoryId(categoryId);
        createDTO.setPrice(new BigDecimal(String.valueOf(price)));
        createDTO.setDescription(description);
        createDTO.setCondition(condition);
        createDTO.setLongitude(longitude);
        createDTO.setLatitude(latitude);
        createDTO.setLocationDescription(locationDescription);
        createDTO.setImageUrls(imageUrls);

        // 3. 创建商品
        return productService.createProduct(userId, createDTO);
    }

    /**
     * 更新商品
     * 
     * @param id                  商品ID
     * @param name                商品名称
     * @param categoryId          商品分类ID
     * @param price               商品价格
     * @param description         商品描述
     * @param condition           商品成色
     * @param longitude           经度
     * @param latitude            纬度
     * @param locationDescription 位置描述
     * @param files               新上传的图片文件列表
     * @return 更新结果
     */
    @PutMapping(value = "/{id}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Result<Void> updateProduct(
            @PathVariable Long id,
            @RequestParam("userId") Long userId,
            @RequestParam("name") String name,
            @RequestParam("categoryId") Long categoryId,
            @RequestParam("price") Double price,
            @RequestParam("description") String description,
            @RequestParam("condition") String condition,
            @RequestParam("originalPrice") Double originalPrice,
            @RequestParam(value = "longitude", required = false) Double longitude,
            @RequestParam(value = "latitude", required = false) Double latitude,
            @RequestParam(value = "locationDescription", required = false) String locationDescription,
            @RequestParam(value = "files", required = false) List<MultipartFile> files) {

        User userResult = userService.getUserById(userId);
        if (userResult == null) {
            return Result.error(404, "用户不存在");
        }

        // 获取商品详情，判断是否为卖家
        Result<ProductDetailVO> productResult = productService.getProductDetail(id, userId);
        if (productResult.getCode() != 200 || productResult.getData() == null) {
            return Result.error(404, "商品不存在");
        }

        ProductDetailVO productDetail = productResult.getData();
        if (!productDetail.getSellerId().equals(userId)) {
            return Result.error(403, "无权操作他人商品");
        }

        // 删除旧的商品图片
        Result<Void> deleteResult = productImageService.deleteProductImages(id);
        if (deleteResult.getCode() != 200) {
            return Result.error(500, "删除旧图片失败");
        }

        // 处理图片
        List<String> finalImageUrls = new ArrayList<>();

        // 上传新图片
        if (files != null && !files.isEmpty()) {
            for (MultipartFile file : files) {
                if (!file.isEmpty()) {
                    Result<String> uploadResult = productService.uploadProductImage(userId, file);
                    if (uploadResult.getCode() == 200 && uploadResult.getData() != null) {
                        finalImageUrls.add(uploadResult.getData());
                    } else {
                        return Result.error(500, "图片上传失败");
                    }
                }
            }
        }

        if (finalImageUrls.isEmpty()) {
            return Result.error(400, "商品至少需要一张图片");
        }

        // 创建更新DTO
        ProductUpdateDTO updateDTO = new ProductUpdateDTO();
        updateDTO.setId(id);
        updateDTO.setName(name);
        updateDTO.setCategoryId(categoryId);
        updateDTO.setPrice(new BigDecimal(String.valueOf(price)));
        updateDTO.setOriginalPrice(BigDecimal.valueOf(originalPrice));
        updateDTO.setDescription(description);
        updateDTO.setCondition(condition);
        updateDTO.setImageUrls(finalImageUrls);

        if (longitude != null && latitude != null) {
            updateDTO.setLongitude(new BigDecimal(String.valueOf(longitude)));
            updateDTO.setLatitude(new BigDecimal(String.valueOf(latitude)));
        }

        if (locationDescription != null) {
            updateDTO.setLocationDescription(locationDescription);
        }

        // 更新商品
        return productService.updateProduct(id, userId, updateDTO);
    }

    /**
     * 删除商品
     * 
     * @param id        商品ID
     * @param principal 当前登录用户
     * @return 删除结果
     */
    @DeleteMapping("/{id}")
    @PreAuthorize("isAuthenticated()")
    public Result<Void> deleteProduct(
            @PathVariable Long id,
            Principal principal) {
        Result<User> userResult = userService.getByUsername(principal.getName());
        if (userResult.getCode() != 200) {
            return Result.error(userResult.getCode(), userResult.getMessage());
        }
        return productService.deleteProduct(id, userResult.getData().getId());
    }

    /**
     * 修改商品状态
     * 
     * @param id        商品ID
     * @param principal 当前登录用户
     * @param status    商品状态：on_sale, sold, off_shelf
     * @return 状态更新结果
     */
    @PutMapping("/{id}/status")
    @PreAuthorize("isAuthenticated()")
    public Result<Void> updateProductStatus(
            @PathVariable Long id,
            Principal principal,
            @RequestParam String status) {
        Result<User> userResult = userService.getByUsername(principal.getName());
        if (userResult.getCode() != 200) {
            return Result.error(userResult.getCode(), userResult.getMessage());
        }
        return productService.updateProductStatus(id, userResult.getData().getId(), status);
    }

    /**
     * 增加商品浏览量
     * 
     * @param id 商品ID
     * @return 更新后的浏览量
     */
    @PostMapping("/{id}/view")
    public Result<Integer> increaseProductViews(@PathVariable Long id) {
        return productService.increaseProductViews(id);
    }

    /**
     * 获取所有商品分类
     * 
     * @return 商品分类列表
     */
    @GetMapping("/categories")
    public Result<List<CategoryVO>> getAllCategories() {
        return categoryService.getAllCategories();
    }

    /**
     * 获取指定分类下的商品
     * 
     * @param categoryId 分类ID
     * @param page       页码
     * @param limit      每页数量
     * @param sort       排序字段
     * @param order      排序方式
     * @param principal  当前登录用户
     * @return 分类下的商品列表
     */
    @GetMapping("/categories/{categoryId}/products")
    public Result<Page<ProductListVO>> getProductsByCategory(
            @PathVariable Long categoryId,
            @RequestParam(required = false, defaultValue = "0") int page,
            @RequestParam(required = false, defaultValue = "10") int limit,
            @RequestParam(required = false, defaultValue = "createdAt") String sort,
            @RequestParam(required = false, defaultValue = "desc") String order,
            Principal principal) {

        Long currentUserId = null;
        if (principal != null) {
            Result<User> userResult = userService.getByUsername(principal.getName());
            if (userResult.getCode() == 200 && userResult.getData() != null) {
                currentUserId = userResult.getData().getId();
            }
        }

        Pageable pageable = PageRequest.of(page, limit);
        return productService.getProductList(categoryId, null, null, null, null,
                sort, order, null, null, pageable, currentUserId);
    }

    /**
     * 获取商品图片列表
     * 
     * @param productId 商品ID
     * @return 商品图片列表
     */
    @GetMapping("/{productId}/images")
    public Result<List<ProductImageVO>> getProductImages(@PathVariable Long productId) {
        return productService.getProductImages(productId);
    }

    /**
     * 获取热门商品列表
     * 
     * @param page     页码
     * @param pageSize 每页数量
     * @return 热门商品列表分页结果
     */
    @GetMapping("/popular")
    public Result<Page<ProductListVO>> getPopularProducts(
            @RequestParam(required = false, defaultValue = "0") int page,
            @RequestParam(required = false, defaultValue = "8") int pageSize) {

        Pageable pageable = PageRequest.of(page, pageSize);
        return productService.getPopularProducts(pageable);
    }

    /**
     * 获取推荐商品列表
     * 
     * @param categoryId 分类ID（可选，如果提供则推荐同类商品）
     * @param limit      返回数量限制（可选，默认为8）
     * @param page       页码（可选，默认为0）
     * @param pageSize   每页数量（可选，默认为8）
     * @param principal  当前登录用户
     * @return 推荐商品列表分页结果
     */
    @GetMapping("/recommendations")
    public Result<Page<ProductListVO>> getRecommendedProducts(
            @RequestParam(required = false) Long categoryId,
            @RequestParam(required = false, defaultValue = "8") Integer limit,
            @RequestParam(required = false, defaultValue = "0") Integer page,
            @RequestParam(required = false, defaultValue = "8") Integer pageSize,
            Principal principal) {

        Long currentUserId = null;
        if (principal != null) {
            Result<User> userResult = userService.getByUsername(principal.getName());
            if (userResult.getCode() == 200 && userResult.getData() != null) {
                currentUserId = userResult.getData().getId();
            }
        }

        Pageable pageable = PageRequest.of(page, pageSize);
        return productService.getRecommendedProducts(categoryId, currentUserId, limit, pageable);
    }

    /**
     * 获取附近商品列表
     * 
     * @param longitude 经度
     * @param latitude  纬度
     * @param radius    搜索半径（米），默认5000
     * @param limit     返回数量限制，默认20
     * @return 附近商品列表
     */
    @GetMapping("/nearby")
    public Result<List<ProductListVO>> getProductsNearby(
            @RequestParam Double longitude,
            @RequestParam Double latitude,
            @RequestParam(required = false) Integer radius,
            @RequestParam(required = false, defaultValue = "20") Integer limit) {

        return productService.getProductsNearby(longitude, latitude, radius, limit);
    }

    /**
     * 收藏商品
     * 
     * @param id     商品ID
     * @param userId 用户ID（从请求体或URL参数中获取）
     * @return 操作结果
     */
    @PostMapping("/{id}/favorite")
    public Result<Object> favoriteProduct(
            @PathVariable Long id,
            @RequestParam(required = false) Long userId,
            @RequestBody(required = false) Object body) {

        log.info("收藏商品请求: id={}, userId={}, body={}", id, userId, body);

        // 从请求体中提取userId（如果存在）
        if (userId == null && body != null && body instanceof java.util.Map) {
            java.util.Map<?, ?> map = (java.util.Map<?, ?>) body;
            if (map.containsKey("userId")) {
                try {
                    userId = Long.valueOf(map.get("userId").toString());
                } catch (Exception e) {
                    log.error("解析userId失败", e);
                }
            }
        }

        // 验证userId是否存在
        if (userId == null) {
            return Result.error(400, "缺少用户ID");
        }

        // 调用收藏服务添加收藏
        Result<Void> result = favoriteService.addFavorite(userId, id);

        if (result.getCode() == 200) {
            return Result.success(java.util.Map.of("favorited", true), "收藏成功");
        } else {
            return Result.error(result.getCode(), result.getMessage());
        }
    }

    /**
     * 取消收藏商品
     * 
     * @param id     商品ID
     * @param userId 用户ID（从URL参数中获取）
     * @return 操作结果
     */
    @DeleteMapping("/{id}/favorite")
    public Result<Object> unfavoriteProduct(
            @PathVariable Long id,
            @RequestParam(required = true) Long userId) {

        log.info("取消收藏商品请求: id={}, userId={}", id, userId);

        // 验证用户是否存在
        User user = userService.getUserById(userId);
        if (user == null) {
            return Result.error(404, "用户不存在");
        }

        // 调用收藏服务取消收藏
        Result<Void> result = favoriteService.removeFavorite(userId, id);

        if (result.getCode() == 200) {
            return Result.success(java.util.Map.of("favorited", false), "取消收藏成功");
        } else {
            return Result.error(result.getCode(), result.getMessage());
        }
    }

    /**
     * 检查商品是否已收藏
     * 
     * @param id     商品ID
     * @param userId 用户ID（从URL参数中获取）
     * @return 是否已收藏
     */
    @GetMapping("/{id}/favorite")
    public Result<Object> checkFavorite(
            @PathVariable Long id,
            @RequestParam(required = true) Long userId) {

        log.info("检查商品收藏状态: id={}, userId={}", id, userId);

        // 验证用户是否存在
        User user = userService.getUserById(userId);
        if (user == null) {
            return Result.error(404, "用户不存在");
        }

        Boolean isFavorite = favoriteService.isFavorite(userId, id);
        return Result.success(java.util.Map.of("favorited", isFavorite), "获取成功");
    }

    /**
     * 联系卖家
     * 
     * @param id        商品ID
     * @param principal 当前登录用户
     * @param message   联系信息
     * @return 操作结果
     */
    @PostMapping("/{id}/contact")
    @PreAuthorize("isAuthenticated()")
    public Result<?> contactSeller(
            @PathVariable Long id,
            Principal principal,
            @RequestBody String message) {
        Result<User> userResult = userService.getByUsername(principal.getName());
        if (userResult.getCode() != 200) {
            return Result.error(userResult.getCode(), userResult.getMessage());
        }

        Long userId = userResult.getData().getId();
        return productService.contactSeller(id, userId, message);
    }

}